package com.kordar.datalist;


import com.kordar.datalist.formatter.Formatter;
import lombok.SneakyThrows;

import java.lang.reflect.Field;
import java.util.*;


public class DatalistService {

    protected String getLabel(Field field) {
        boolean exist = field.isAnnotationPresent(Label.class);
        if (!exist) {
            return field.getName();
        }
        Label label = field.getAnnotation(Label.class);
        return label.value();
    }

    @SneakyThrows
    protected Map<String, Object> getColumn(Field field) {
        boolean exist = field.isAnnotationPresent(DataColumn.class);
        if (!exist) {
            return null;
        }
        Map<String, Object> column = new HashMap<>();
        DataColumn annotation = field.getAnnotation(DataColumn.class);

        // 生成label
        if (!"".equals(annotation.alias().trim())) {
            column.put("key", annotation.alias());
        } else {
            column.put("key", field.getName());
        }

        // 获取formatter
        Class<?> format = annotation.formatter();

        Formatter<?> formatter = (Formatter<?>) format.newInstance();
        column.put("formatter", formatter);
        column.put("params", annotation.params());
        if (annotation.field().equals("")) {
            column.put("field", field.getName());
        } else {
            column.put("field", annotation.field());
        }
        return column;
    }

    public <T> List<Map<String, Object>> render(List<T> list, Class<T> classz) {

        Field[] fields = classz.getDeclaredFields();
        List<Map<String, Object>> data = new ArrayList<>();
        List<Map<String, Object>> columns = new ArrayList<>();  // 反射列
        Map<String, Field> cacheList = new HashMap<>();  // 反射缓存

        try {

            // 初始化columns
            for (Field field : fields) {
                Map<String, Object> column = getColumn(field);
                if (column == null) {
                    continue;
                }
                columns.add(column);    // 处理列map
                cacheList.put(field.getName(), field);  // 写入缓存
            }

            for (int i = 0; i < list.size(); i++) {
                T elem = list.get(i);  // 获取当前元素
                Map<String, Object> row = new HashMap<>();
                Iterator<Map<String, Object>> it = columns.iterator();
                for (int index = 0; it.hasNext(); index++) {
                    Map<String, Object> column = it.next();
                    String fieldName = (String) column.get("field");
                    Field field = cacheList.get(fieldName);
                    field.setAccessible(true);
                    Object value = field.get(elem);  // 反射获取field对应的值
                    Formatter<?> formatter = (Formatter<?>) column.get("formatter");
                    row.put((String) column.get("key"), formatter.format(value, (String) column.get("params"), elem));
                }
                data.add(row);
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
        return data;
    }

    public <T> List<Map<String, Object>> renderVo(List<T> list, Class<T> classz, Class<?> classzVo) {

        Field[] fieldsVo = classzVo.getDeclaredFields();
        List<Map<String, Object>> data = new ArrayList<>();
        List<Map<String, Object>> columns = new ArrayList<>();  // 反射列
        Map<String, Field> cacheList = new HashMap<>();  // 反射缓存

        try {

            // 初始化columns
            for (Field field : fieldsVo) {
                Map<String, Object> column = getColumn(field);
                if (column == null) {
                    continue;
                }
                columns.add(column);    // 处理列map
            }

            Field[] fields = classz.getDeclaredFields();
            for (Field field : fields) {
                cacheList.put(field.getName(), field);  // 写入缓存
            }

            for (int i = 0; i < list.size(); i++) {
                T elem = list.get(i);  // 获取当前元素
                Map<String, Object> row = new HashMap<>();
                Iterator<Map<String, Object>> it = columns.iterator();
                while (it.hasNext()) {
                    Map<String, Object> column = it.next();
                    String fieldName = (String) column.get("field");
                    Field field = cacheList.get(fieldName);
                    field.setAccessible(true);
                    Object value = field.get(elem);  // 反射获取field对应的值
                    Formatter<?> formatter = (Formatter<?>) column.get("formatter");
                    row.put((String) column.get("key"), formatter.format(value, (String) column.get("params"), elem));
                }
                data.add(row);
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
        return data;
    }


}
